﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Access.PowerTools.Automation.Engine;
using Access.PowerTools.AbstractionLayer;
using Access.PowerTools.Utilities;

namespace Access.PowerTools.TestConsole
{
    [TestFixture]
    public class TestSet_0007_v_0_0_1_Fixes
    {
        [SetUp]
        public void Setup()
        {
            Access.PowerTools.Settings.Globals.Init();
            //Access.PowerTools.Settings.Globals.SimulationModeOn = true;

            //Access.PowerTools.Settings.Globals.HostApplication =
            //    new Access.PowerTools.Simulation.Engine.SimulationCommunicationBridge();

            string backUpFolder = Access.PowerTools.Settings.Globals.ExportFilesFolder;
            string restoreFolder = Access.PowerTools.Settings.Globals.RestoredFilesFolder;

            //Console.WriteLine("BackUp folder = '{0}'", backUpFolder);
            //Console.WriteLine("Restore folder = '{0}'", restoreFolder);

            Access.PowerTools.Utilities.FilesAndFolders.ClearFolder(backUpFolder);
            Access.PowerTools.Utilities.FilesAndFolders.ClearFolder(restoreFolder);

        }

        [TearDown]
        public void TearDown()
        {
        }

        #region Absolutely NO automatic backing up of linked tables allowed (WH) + Program hung on trying to export network linked table (WH)
        [Test]
        public void Test_001_DoNotBackupLinkedTables()
        {
            //TODO: 03.2-11     Absolutely NO automatic backing up of linked tables allowed (WH) 	
            //                  Proposed 	Issue 	High 	Fri at 4:54 PM
            Console.WriteLine(DateTime.Now.ToString());
            Console.WriteLine("Starting backup test...");

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            IHostComunicationBridge iHost = null;

            string dbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "nw_withLinkedTables.mdb";
            bool ret = true;

            List<AccessDatabaseObjectInfo> list = null;

            try
            {
                Console.WriteLine("Starting MS Access application...");

                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                Console.WriteLine("Opening currentdb '{0}'...", dbFullPath);
                bridge.OpenCurrentDatabase(dbFullPath);

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1} - '{2}'",
                    iHost.ApplicationName, iHost.ApplicationVersion, iHost.CurrentDatabaseFullPath);

                list = iHost.GetObjectsList();

                Console.WriteLine("Starting back-up...");
                Access.PowerTools.Settings.Globals.HostApplication =
                    bridge;

                AccessApplication application = new AccessApplication();

                Access.PowerTools.Database.BackUp.Plug_In.BackUpAgent
                    backup = new Access.PowerTools.Database.BackUp.Plug_In.BackUpAgent(application);

                string backUpFolder = Access.PowerTools.Settings.Globals.ExportFilesFolder;
                Access.PowerTools.Utilities.FilesAndFolders.ClearFolder(backUpFolder);

                backup.ReportProgressStatus += new EventHandler<RunProgressEventArgs>(ReportProgressStatus);

                backup.BackUpDatabase(backUpFolder);

                Console.WriteLine("Back-up finished, exported {0} objects.", list.Count);

                Console.WriteLine("Exiting host application...");

                bridge.QuitHostApplication();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = false;
            }
            finally
            {
                if (bridge != null)
                    bridge.QuitHostApplication();
                bridge = null;

                Access.PowerTools.Settings.Globals.HostApplication = null;
                GC.Collect();
            }

            Console.WriteLine("Test DONE.");
            Console.WriteLine(DateTime.Now.ToString());

            ret = list.Count == 0; 
            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");

        }
        #endregion

        #region Export fails on any linked table that doesn't actually exist (WH)
        [Test]
        public void Test_002_DoNotBackupBrokenLinkedTables()
        {
            //TODO: 10.1-17 	Export fails on any linked table that doesn't actually exist (WH) 	
            //                  Proposed 	Issue 	High 	Thu at 6:52 PM
            Console.WriteLine(DateTime.Now.ToString());
            Console.WriteLine("Starting backup test...");

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            IHostComunicationBridge iHost = null;

            string dbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "nw_withLinkedTables.mdb";
            bool ret = true;

            List<AccessDatabaseObjectInfo> list = null;

            try
            {
                Console.WriteLine("Starting MS Access application...");

                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                Console.WriteLine("Opening currentdb '{0}'...", dbFullPath);
                bridge.OpenCurrentDatabase(dbFullPath);

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1} - '{2}'",
                    iHost.ApplicationName, iHost.ApplicationVersion, iHost.CurrentDatabaseFullPath);

                list = iHost.GetObjectsList();

                Console.WriteLine("Starting back-up...");
                Access.PowerTools.Settings.Globals.HostApplication =
                    bridge;

                AccessApplication application = new AccessApplication();

                Access.PowerTools.Database.BackUp.Plug_In.BackUpAgent
                    backup = new Access.PowerTools.Database.BackUp.Plug_In.BackUpAgent(application);

                string backUpFolder = Access.PowerTools.Settings.Globals.ExportFilesFolder;
                Access.PowerTools.Utilities.FilesAndFolders.ClearFolder(backUpFolder);

                backup.ReportProgressStatus += new EventHandler<RunProgressEventArgs>(ReportProgressStatus);

                backup.BackUpDatabase(backUpFolder);

                Console.WriteLine("Back-up finished, exported {0} objects.", list.Count);

                Console.WriteLine("Exiting host application...");

                bridge.QuitHostApplication();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = false;
            }
            finally
            {
                if (bridge != null)
                    bridge.QuitHostApplication();
                bridge = null;

                Access.PowerTools.Settings.Globals.HostApplication = null;
                GC.Collect();
            }

            Console.WriteLine("Test DONE.");
            Console.WriteLine(DateTime.Now.ToString());

            ret = list.Count == 0;
            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");

        }
        #endregion


        [Test]
        public void Test_003_EncodeObjectName()
        {

            bool ret = true;

            string objectName = "\n<test>\t";
            //string encodedObjectName = "%0A%3Ctest%3E%09";
            string encodedObjectName = "_x000A__x003C_test_x003E__x0009_";

            Console.WriteLine(Access.PowerTools.Utilities.Strings.EncodeObjectName(objectName));

            ret = (String.Compare(encodedObjectName, Access.PowerTools.Utilities.Strings.EncodeObjectName(objectName)) == 0);
    
            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }

        [Test]
        public void Test_004_DecodeObjectName()
        {

            bool ret = true;

            string decodedObjectName = "\n<test>\t";
            //string objectName = "%0A%3Ctest%3E%09";
            string objectName = "_x000A__x003C_test_x003E__x0009_";

            Console.WriteLine(Access.PowerTools.Utilities.Strings.DecodeObjectName(objectName));

            ret = (String.Compare(decodedObjectName, Access.PowerTools.Utilities.Strings.DecodeObjectName(objectName)) == 0);

            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }


        #region Export fails on any object with a "/", ")" or "(" in the file name (WH)
        [Test]
        public void Test_005_BackUpObjectsWithSpecialCharsInTheirNames()
        {
            //TODO: 10.1-17 	Export fails on any linked table that doesn't actually exist (WH) 	
            //                  Proposed 	Issue 	High 	Thu at 6:52 PM
            Console.WriteLine(DateTime.Now.ToString());
            Console.WriteLine("Starting backup test...");

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            IHostComunicationBridge iHost = null;

            string dbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "nw_ObjectNamesWithSpecialChars.mdb";
            bool ret = true;

            List<AccessDatabaseObjectInfo> list = null;

            try
            {
                Console.WriteLine("Starting MS Access application...");

                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                Console.WriteLine("Opening currentdb '{0}'...", dbFullPath);
                bridge.OpenCurrentDatabase(dbFullPath);

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1} - '{2}'",
                    iHost.ApplicationName, iHost.ApplicationVersion, iHost.CurrentDatabaseFullPath);

                list = iHost.GetObjectsList();

                Console.WriteLine("Starting back-up...");
                Access.PowerTools.Settings.Globals.HostApplication =
                    bridge;

                AccessApplication application = new AccessApplication();

                Access.PowerTools.Database.BackUp.Plug_In.BackUpAgent
                    backup = new Access.PowerTools.Database.BackUp.Plug_In.BackUpAgent(application);

                string backUpFolder = Access.PowerTools.Settings.Globals.ExportFilesFolder;
                Access.PowerTools.Utilities.FilesAndFolders.ClearFolder(backUpFolder);

                backup.ReportProgressStatus += new EventHandler<RunProgressEventArgs>(ReportProgressStatus);

                backup.BackUpDatabase(backUpFolder);

                Console.WriteLine("Back-up finished, exported {0} objects.", list.Count);

                Console.WriteLine("Exiting host application...");

                bridge.QuitHostApplication();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = false;
            }
            finally
            {
                if (bridge != null)
                    bridge.QuitHostApplication();
                bridge = null;

                Access.PowerTools.Settings.Globals.HostApplication = null;
                GC.Collect();
            }

            Console.WriteLine("Test DONE.");
            Console.WriteLine(DateTime.Now.ToString());

            ret = list.Count == 6;
            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");

        }

        [Test]
        public void Test_006_RestoreObjectsWithSpecialCharsInTheirNamesFromTestBackUp()
        {
            Console.WriteLine(DateTime.Now.ToString());
            Console.WriteLine("Starting restore test...");

            bool ret = true;

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            Access.PowerTools.Settings.Globals.HostApplication =
                bridge;

            IHostComunicationBridge iHost = null;

            string seedDbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "nw.mdb";

            string dbFullPath = Access.PowerTools.Settings.Globals.RestoredFilesFolder +
                                 "nw_ObjectNamesWithSpecialChars_RESTORED.mdb";

            string restoreFolder = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                  "BackupObjectNamesWithSpecialChars";
            
            //Access.PowerTools.Utilities.FilesAndFolders.ClearFolder(restoreFolder);
            //string dbFullPath = restoreFolder + "RESTORED_Northwind.mdb";

            try
            {
                Console.WriteLine("Copying test db to '{0}'...", dbFullPath);
                System.IO.File.Copy(seedDbFullPath, dbFullPath);

                Console.WriteLine("Starting MS Access application...");

                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                Access.PowerTools.Utilities.FilesAndFolders.BackUpFile(dbFullPath);
                Access.PowerTools.Utilities.FilesAndFolders.BackUpFile(dbFullPath);
                Access.PowerTools.Utilities.FilesAndFolders.BackUpFile(dbFullPath);

                Console.WriteLine("Opening currentdb '{0}'...", dbFullPath);
                bridge.OpenCurrentDatabase(dbFullPath);

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1}", iHost.ApplicationName, iHost.ApplicationVersion);

                Console.WriteLine("Starting restore...");
                Access.PowerTools.Settings.Globals.HostApplication =
                    bridge;

                AccessApplication application = new AccessApplication();

                Access.PowerTools.Database.Restore.Plug_In.RestoreAgent
                    backup = new Access.PowerTools.Database.Restore.Plug_In.RestoreAgent(application);

                backup.ReportProgressStatus += new EventHandler<RunProgressEventArgs>(ReportProgressStatus);

                backup.RestoreDatabase(restoreFolder);

                Console.WriteLine("Closing currentdb '{0}'...", dbFullPath);
                bridge.CloseCurrentDatabase();

                System.Threading.Thread.Sleep(500);

                Console.WriteLine("Compacting current database...");
                bridge.CompactCurrentDatabase();

                System.Threading.Thread.Sleep(500);

                //Console.WriteLine("Reopening currentdb '{0}'...", dbFullPath);
                //bridge.OpenCurrentDatabase(dbFullPath);

                Console.WriteLine("Listing current db objects...");
                List<AccessDatabaseObjectInfo> list = iHost.GetObjectsList();

                foreach (AccessDatabaseObjectInfo objectInfo in list)
                {
                    Console.WriteLine("{0} - {1}", objectInfo.Type, objectInfo.Name);
                }

                Console.WriteLine("Restore finished, imported {0} objects.", list.Count);

                Console.WriteLine("Exiting host application...");

                bridge.CloseCurrentDatabase();
                System.Threading.Thread.Sleep(500);

                bridge.QuitHostApplication();

                bridge = null;

            }
            catch (Exception ex)
            {
                Console.WriteLine("Test_006_RestoreDbFromTestBackUp: " + ex.Message);
                Console.WriteLine("STACK TRACE");
                Console.WriteLine(ex.StackTrace);

                ret = false;
            }
            finally
            {
                if (bridge != null)
                    bridge.QuitHostApplication();
                bridge = null;

                Access.PowerTools.Settings.Globals.HostApplication = null;
                GC.Collect();
            }

            Console.WriteLine("Test DONE.");
            Console.WriteLine(DateTime.Now.ToString());

            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }
        #endregion

        private void ReportProgressStatus(object sender, RunProgressEventArgs e)
        {
            Console.WriteLine(string.Format("{0:HH:mm:ss.fff}: ", DateTime.Now) +
                          e.Message);
            //System.Threading.Thread.Sleep(10);
        }



    }
}